﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static An_Im.PowerV.TriggerLinkList;

namespace An_Im.PowerV
{

    /// <summary>
    /// 链式触发器。
    /// </summary>
    internal class TriggerLinkList : PowerVCodeBase
    {

        /// <summary>
        /// 延迟事件。
        /// </summary>
        public struct DelayEventInfomation
        {
            public int Millsecond;
            public string EventName;

            public DelayEventInfomation(int millsecond, string eventName)
            {
                Millsecond = millsecond;
                EventName = eventName;
            }

        }

        /// <summary>
        /// 列表长度。
        /// </summary>
        public int Length
        {
            get => _length;
            set
            {
                if (value <= 0)
                    _length = 1;
                else
                    _length = value;
            }
        }

        private int _length = 1;

        private DelayEventInfomation[] _delayEventInfomations;

        public TriggerLinkList(DelayEventInfomation[] delayEventInfomations)
        {
            if (delayEventInfomations == null)
            {
                throw new ArgumentNullException();
            }
            if (delayEventInfomations.Length == 0)
            {
                throw new ArgumentNullException("列表信息至少存在一条事件。");
            }
            _delayEventInfomations = delayEventInfomations;
            _length = _delayEventInfomations.Length;
        }


        /// <summary>
        /// 声明部分。
        /// </summary>
        private void DeclarePart(StringBuilder sb)
        {
            sb.AppendLine(string.Format("Private Const 延时列表长度 = {0}", Length));
            sb.AppendLine("Private 延时器ID As Integer, 延时时间列表(1 To 延时列表长度) As Integer, 延时事件列表(1 To 延时列表长度) As LongPtr, 延时定时器 As LongPtr");
            sb.AppendLine();
        }

        private void InitializePart(StringBuilder sb)
        {
            sb.AppendLine("Private Function 初始化()");
            sb.AppendLine("    延时器初始化");
            sb.AppendLine("End Function");
            sb.AppendLine();
            sb.AppendLine("Private Function 延时器初始化()");
            sb.AppendLine("    延时器ID = 0");
            sb.AppendLine("    延时定时器 = 0");
            for (int i = 1; i <= _length; i++)
            {
                var info = _delayEventInfomations[i - 1];
                var ms = info.Millsecond; var name = info.EventName;
                sb.AppendLine(String.Format("    延时时间列表({0}) = {1}: 延时事件列表({0}) = pv.HandleGet(AddressOf {2})", i, ms, name));
            }
            sb.AppendLine("End Function");
            sb.AppendLine();
        }

        private void ManageTriggerLinkList(StringBuilder sb)
        {
            sb.AppendLine("Public Sub 开启延时触发链()");
            sb.AppendLine("    If 延时定时器 = 0 Then");
            sb.AppendLine("        激活下一延时器");
            sb.AppendLine("    End If");
            sb.AppendLine("End Sub");
            sb.AppendLine();

            sb.AppendLine("Public Function 终止触发链()");
            sb.AppendLine("    KillTimer 0, 延时定时器");
            sb.AppendLine("    延时定时器 = 0");
            sb.AppendLine("End Function");
            sb.AppendLine();

            sb.AppendLine("Private Function 终止当前延时器()");
            sb.AppendLine("        KillTimer 0, 延时定时器");
            sb.AppendLine("End Function");
            sb.AppendLine();

            sb.AppendLine("\' -1 下标越界 -2 列表中存在未定义。0 正常开始");
            sb.AppendLine("Private Function 激活下一延时器() As Integer");
            sb.AppendLine("    延时器ID = 延时器ID + 1");
            sb.AppendLine("    If (延时器ID < 1 Or 延时器ID > 延时列表长度) Then");
            sb.AppendLine("        激活下一延时器 = -1: Exit Function");
            sb.AppendLine("    End If");
            sb.AppendLine("    If (延时时间列表(延时器ID) * 延时事件列表(延时器ID) = 0) Then");
            sb.AppendLine("        激活下一延时器 = -2: Exit Function");
            sb.AppendLine("    End If");
            sb.AppendLine("    延时定时器 = SetTimer(0, 0, 延时时间列表(延时器ID), 延时事件列表(延时器ID))");
            sb.AppendLine("    激活下一延时器 = 0");
            sb.AppendLine("End Function");
            sb.AppendLine();
        }



        private void EventsImplement(StringBuilder sb)
        {
            for (int i = 1; i <= _length; i++)
            {
                var info = _delayEventInfomations[i - 1];
                var ms = info.Millsecond; var name = info.EventName;
                if (i != 1)
                    sb.AppendLine(string.Format("\' 【{0}】事件，在【{1}】事件触发后时隔{2}ms触发。", name, _delayEventInfomations[i - 2].EventName, ms));
                else
                    sb.AppendLine(string.Format("\' 【{0}】事件，时隔{1}ms触发。", name, ms));
                sb.AppendLine(string.Format("Private Function {0}() As LongPtr", name));
                sb.AppendLine("    终止当前延时器");
                if (i != _length)
                    sb.AppendLine("    激活下一延时器");
                sb.AppendLine("    On Error GoTo RETURNTAG");
                sb.AppendLine("    ");
                sb.AppendLine("    \'\'\' Region TODO");
                sb.AppendLine("    \' 请于此处编写");
                sb.AppendLine("    \'\'\' End Region");
                sb.AppendLine("    ");
                sb.AppendLine("RETURNTAG:");
                sb.AppendLine("    ");
                sb.AppendLine(string.Format("    {0} = 0", name));
                sb.AppendLine("End Function");
                sb.AppendLine();
            }

        }
       
        public override string CreatePowerVCode()
        {
            var sb = new StringBuilder();

            DeclarePart(sb);
            EventsImplement(sb);
            InitializePart(sb);
            ManageTriggerLinkList(sb);



            return sb.ToString();

        }
    }
}
